#import "BWCrossStitchLineTool.h"
#import "BWCrossStitchChangeList.h"


@implementation BWCrossStitchLineTool

- (void) drawLineFromRow: (int) row1   column: (int) column1
                   toRow: (int) row2   column: (int) column2
              withThread: (BWThread *) thread
{
    // invalidate old change list in view
    [changeList purge];

    int dx = column2 - column1;
    int dy = row2 - row1;

    [changeList addStitchWithThread: thread
                atRow: row1
                column: column1];

    // adapted from "lineImproved"
    // http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
    if (abs(dx) > abs(dy)) {
        float m = (float) dy / (float) dx;
        float b = row1 - m * column1;
        dx = (dx < 0) ? -1 : 1;
        while (column1 != column2) {
            column1 += dx;
            [changeList addStitchWithThread: thread
                        atRow: round(m * column1 + b)
                        column: column1];
        }

    } else if (dy != 0) {
        float m = (float) dx / (float) dy;
        float b = column1 - m * row1;
        dy = (dy < 0) ? -1 : 1;
        while (row1 != row2) {
            row1 += dy;
            [changeList addStitchWithThread: thread
                        atRow: row1
                        column: round (m * row1 + b)];
        }
    }
    
    [self invalidateRectAt: row1  column: column1
          row: row2  column: column2];

} // drawLineFromRow


- (void) startDragAtRow: (int) row  
                 column: (int) column
                 thread: (BWThread *) thread
{
    startRow = endRow = row;
    startColumn = endColumn = column;

    [self drawLineFromRow: startRow  column: startColumn
          toRow: endRow  column: endColumn
        withThread: thread];

} // startDragAtRow


- (void) continueDragAtRow: (int) row
                    column: (int) column
                    thread: (BWThread *) thread
{
    [self invalidateRectAt: startRow  column: startColumn
          row: endRow  column:  endColumn];
    
    if ([self isConstrained]) {
        int rowDelta, columnDelta;

        rowDelta = abs (startRow - row);
        columnDelta = abs (startColumn - column);

        if (rowDelta > columnDelta) {
            // vertical line
            column = startColumn;

        } else if (columnDelta >= rowDelta) {  // >= to prevent diagonal line
            // horizontal line
            row = startRow;
        }
    }

    endRow = row;
    endColumn = column;

    [self drawLineFromRow: startRow  column: startColumn
          toRow: endRow  column: endColumn
        withThread: thread];

} // continueDragAtRow


- (NSString *) name
{
    return (@"Draw lines with cross stitches");
} // name

@end // BWCrossStitchLineTool

